/* COPYRIGHT_CHUNFENG */
#include "cf_common.h"
#include "cf_list.h"

void cf_list_init(CFListHead* node)
{
    node->prev=node;
    node->next=node;
}

void cf_list_insert_next(CFListHead* node, CFListHead* to_insert)
{
    node->next->prev = to_insert;
    to_insert->next = node->next;
    to_insert->prev = node;
    node->next = to_insert;
}

void cf_list_insert_pre(CFListHead* node, CFListHead* to_insert)
{
    node->prev->next = to_insert;
    to_insert->next = node;
    to_insert->prev = node->prev;
    node->prev = to_insert;
}

int cf_list_del(CFListHead* to_delete)
{
    if(to_delete->next == to_delete)
        return -1;
    to_delete->prev->next = to_delete->next;
    to_delete->next->prev = to_delete->prev;
    return 0;
}

CFGList* CFGListAppend(CFGList* head, void* data)
{
	CFGList *newNode;
	
	if (!(newNode = (CFGList*)malloc(sizeof(CFGList)))) {
		goto ERR_OUT;
	}
	CFListInit(&newNode->list);
	newNode->data = data;
	if (head) {
		CFListAppend(&head->list, &newNode->list);
		return head;
	} else {
		return newNode;
	}
ERR_OUT:
	return NULL;
}

CFGList* CFGListPrepend(CFGList* head, void* data)
{
	CFGList *newNode;
	
	if (!(newNode = (CFGList*)malloc(sizeof(CFGList)))) {
		goto ERR_OUT;
	}
	CFListInit(&newNode->list);
	newNode->data = data;
	if (head) {
		CFListPrepend(&head->list, &newNode->list);
	}
	return newNode;
ERR_OUT:
	return NULL;	
}

CFGList* CFGListGetPrev(CFGList* head)
{
	if (!head) {
		return NULL;
	} else {
		return CFListContainerGetPrev(head, CFGList, list);
	}
}

CFGList* CFGListGetNext(CFGList* head)
{
	if (!head) {
		return NULL;
	} else {
		return CFListContainerGetNext(head, CFGList, list);
	}
}

CFGList* CFGListDel(CFGList* head, CFGList* toDel)
{
	CFGList* ret;
	
	if (!head) {
		return NULL;
	} else {
		if (CFGListGetNext(head) == toDel) {
			free(toDel);
			return NULL;
		} else {
			if (head == toDel) {
				ret = CFGListGetNext(head);
			} else {
				ret = head;
			}
			CFListDel(&toDel->list);
			free(toDel);			
			return ret;
		}
	}
}

CFGList* CFGListDelFreeData(CFGList* head, CFGList* toDel, int(*freeFunc)(void*))
{
	CFGList* ret;
	
	if (!head) {
		return NULL;
	} else {
		if (CFGListGetNext(head) == toDel) {
			freeFunc(toDel->data);
			free(toDel);
			return NULL;
		} else {
			if (head == toDel) {
				ret = CFGListGetNext(head);
			} else {
				ret = head;
			}
			freeFunc(toDel->data);
			CFListDel(&toDel->list);
			free(toDel);			
			return ret;
		}
	}
}

void CFGListForeach(CFGList* head, void(processFunc)(CFGList* node, void* usrData), void* usrData)
{
	CFListContainerForeachSafe(head, node, CFGList, list){
		processFunc(node, usrData);
	}
}

